<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/12/6
 * Time: 13:21
 */

namespace common\business\qywx;


use common\business\DbHandler;
use common\business\EhrHelper;
use common\consts\CommonResources;
use common\helpers\StringUtil;
use common\models\Department;
use common\models\Employee;
use common\models\EmployeeDepartment;
use common\models\kingdee\OrgAdmin;
use common\models\kingdee\Person;
use common\models\Log;
use common\models\qywx\QywxUser;
use common\result\ActionResult;
use yii\db\Exception;
use yii\db\Query;
use yii\db\QueryInterface;

class QywxUserService extends DbHandler
{
    /**
     * @var string
     */
    protected $_hrId;
    public function setHrId($hrId){
        $this->_hrId = $hrId;
    }

    /**
     * @var string
     */
    protected $_department_number;
    public function setDepartmentNumber($department_number){
        $this->_department_number = $department_number;
    }


    /**
     * @param $person array
     * @param $totalResult ActionResult
     * @param $totalCount integer
     * @param callback|null $writeBackHandler
     */
    protected function handleSinglePerson($person, $totalResult, $totalCount, $writeBackHandler = null){
        $api = new QywxUserApiHandler();

        $person['gender'] = EhrHelper::kdGenderToQywxGender($person['gender']);

        $department = Department::findOne(['number' => $person['department_number']]);
        if (!$department){
            $this->addError('Find Department', 'Department Not Found');
            $totalResult->addSubResult(new ActionResult(false, $this->getErrorsMessage()));
            $log = new Log([
                'action' => CommonResources::ACTION_NAME_MSG('Sync', 'Qywx User', sprintf('%s_%s', $person['name'], $person['number'])),
                'memo' => $this->getErrorsMessage(),
            ]);
            $logSaveSuccess = $api->saveLog($log);
            $this->executeWriteBackHandlerWithTotal($totalResult, $totalCount, $writeBackHandler);
            return;
        }
        $person['department'] = strval($department->qywx_id);

        $userid = '';
        $numberOne = StringUtil::isNullOrWhiteSpace($person['number']) ? null : $api->findOne($person['number']);
        $weixinOne = StringUtil::isNullOrWhiteSpace($person['weixin']) ? null : $api->findOne($person['weixin']);
        $mobileOne = StringUtil::isNullOrWhiteSpace($person['mobile']) ? null : $api->findOne($person['mobile']);
        if ($numberOne){
            $userid = $person['number'];
        }
        else {
            if ($weixinOne){
                $userid = $person['weixin'];
            }
            else {
                if ($mobileOne){
                    $userid = $person['mobile'];
                }
            }
        }
        $person['userid'] = $userid;

        $newQywxUser = new QywxUser();
        $newQywxUser->setAttributes($person);

        //没有userid和position，一般是已经离职的员工，所以就不同步
        if (StringUtil::isNullOrWhiteSpace($newQywxUser->userid) && StringUtil::isNullOrWhiteSpace($person['position'])){
            $errMsg = CommonResources::ACTION_NAME_MODEL_FAIL('Sync', 'Qywx User', sprintf('%s_%s', $person['name'], $person['number']), 'userid and position is null');
            $log = new Log([
                'action' => CommonResources::ACTION_NAME_MSG('Sync', 'Qywx User', sprintf('%s_%s', $person['name'], $person['number'])),
                'memo' => 'userid and position is null',
            ]);
            $logSaveSuccess = $api->saveLog($log);
            $totalResult->addSubResult(new ActionResult(false, $errMsg));
        }
        else {
//                    如果userid为空，则取员工号作为userid，如果有人已经用微信号绑定不影响
            if(StringUtil::isNullOrWhiteSpace($newQywxUser->userid)){
                $newQywxUser->userid = $person['number'];
            }
            $qywxUserInDb = QywxUser::findOne([
                'userid' => $newQywxUser->userid,
            ]);

            if (!$qywxUserInDb){
                $totalResult->addSubResult($api->createQywxUser($newQywxUser));
            }
            else {
                $totalResult->addSubResult($api->updateQywxUser($newQywxUser, $qywxUserInDb));
            }
        }

        $this->executeWriteBackHandlerWithTotal($totalResult, $totalCount, $writeBackHandler);
    }


    /**
     * @return QueryInterface
     */
    protected function getBaseQuery(){
        $query = (new Query())->from('T_BD_PERSON TBP')
            ->leftJoin('T_BD_NATIONALITY NAT', 'NAT.FID = TBP.FNATIONALITYID')
            ->leftJoin('T_HR_PERSONCONTACTMETHOD THPCM', 'THPCM.FPERSONID = TBP.FID')
            ->leftJoin('T_HR_PERSONPOSITION THPP', 'THPP.FPERSONID = TBP.FID')
            ->leftJoin('T_ORG_POSITION TOPP', 'TOPP.FID = THPP.FPRIMARYPOSITIONID')
            ->leftJoin('T_ORG_ADMIN TOA', 'TOA.FID = TOPP.FADMINORGUNITID')
            ->select([
                'name' => 'TBP.FNAME_L2',
                'number' => 'TBP.FNUMBER',
                'gender' => 'TBP.FGENDER',
                'birthday' => 'to_char(TBP.FBIRTHDAY , \'yyyy-MM-dd\')',
                'email' => 'TBP.FEMAIL',
                'mobile' => 'TBP.FCELL',
                'id_card_num' => 'TBP.FIDCARDNO',
                'hr_id' => 'TBP.FID',
                'weixin' => 'THPCM.FWEIXIN',
                'telephone' => 'THPCM.FOFFICEPHONE',
                'position' => 'TOPP.FNAME_L2',
                'position_number' => 'TOPP.FNUMBER',
                'department_name' => 'TOA.FNAME_L2',
                'department_number' => 'TOA.FNUMBER',
                'department_display_name' => 'TOA.FDISPLAYNAME_L2',
            ]);
        return $query;
    }

    /**
     * @param callback|null $writeBackHandler
     * @return ActionResult
     */
    public function syncOne($writeBackHandler = null){
        $totalResult = new ActionResult();

        $query = $this->getBaseQuery();
        $person = $query->andFilterWhere([ 'TBP.FID' => $this->_hrId ])->one(Person::getDb());

        if (!$person){
            $this->addError('Find Kingdee Person', 'Person Not Found in Kingdee');
            $totalResult->addSubResult(new ActionResult(false, $this->getErrorsMessage()));
            $this->executeWriteBackHandlerNoTotal($totalResult, $writeBackHandler);
            return $totalResult;
        }

        $this->handleSinglePerson($person, $totalResult, 1, $writeBackHandler);
        return $totalResult;
    }

    /**
     * @param callback|null $writeBackHandler
     * @return ActionResult
     */
    public function sync($writeBackHandler = null){
        if (!StringUtil::isNullOrWhiteSpace($this->_hrId)){
            return $this->syncOne($writeBackHandler);
        }

        $totalResult = new ActionResult();

        $db = Person::getDb();
        if (!StringUtil::isNullOrWhiteSpace($this->_department_number)){
            $org = OrgAdmin::findOne([
                'FNUMBER' => $this->_department_number
            ]);

            $orgIdParams = [
                'fid' => $org->FID
            ];
            $cmd = $db->createCommand('SELECT t.fid FROM T_ORG_ADMIN t START WITH t.fid = :fid CONNECT BY t.fparentid = PRIOR fid', $orgIdParams);
//        $cmd->bindParam('fid', $orgId);
            try {
                $orgIdArr = $cmd->queryColumn();
            } catch (Exception $e) {
                return null;
            }
        }

        $query = $this->getBaseQuery();
        if (!StringUtil::isNullOrWhiteSpace($this->_department_number)){
            $query->andFilterWhere([
                'in' , 'THPP.FPERSONDEP', $orgIdArr
            ]);
        }
        $query->orderBy([
            'TBP.FID' => SORT_ASC,
        ]);

        $totalCount = $query->count('*', $db);

        $offset = 0;
        $pageSize = 100;
        $count = $pageSize;

        while ($count >= $pageSize) {
            $all = $query->offset($offset)->limit($pageSize)->all($db);
            $count = count($all);
            $offset += $pageSize;
            foreach ($all as $person){
                $this->handleSinglePerson($person, $totalResult, $totalCount, $writeBackHandler);
            }
        }
        return $totalResult;
    }
}